package com.xiaodou.mjf.application.basic.utils;

import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.subject.Subject;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.xiaodou.mjf.application.basic.auth.AuthorizingRealm;
import com.xiaodou.mjf.application.basic.service.MenuService;
import com.xiaodou.mjf.application.basic.service.OperatorService;
import com.xiaodou.mjf.application.basic.service.RoleService;
import com.xiaodou.mjf.entity.basic.Menu;
import com.xiaodou.mjf.entity.basic.Operator;
import com.xiaodou.mjf.entity.basic.Role;
import com.xiaodou.mjf.infrastructure.common.context.SpringContextHolder;

public class OperatorUtils {

	
	private static OperatorService operatorService = SpringContextHolder.getBean(OperatorService.class);
	private static RoleService roleService = SpringContextHolder.getBean(RoleService.class);
	private static MenuService menuService = SpringContextHolder.getBean(MenuService.class);



	public static final String CACHE_OPERATOR = "operator";
	public static final String CACHE_ROLE_LIST = "roleList";
	public static final String CACHE_MENU_LIST = "menuList";
	
	public static Operator getOperator(){
		Operator operator = (Operator)getCache(CACHE_OPERATOR);
		if (operator == null){
			try{
				Subject subject = SecurityUtils.getSubject();
				AuthorizingRealm.Principal principal = (AuthorizingRealm.Principal)subject.getPrincipal();
				if (principal!=null){
					operator = operatorService.get(principal.getId());
//					Hibernate.initialize(Operator.getRoleList());
					putCache(CACHE_OPERATOR, operator);
				}
			}catch (UnavailableSecurityManagerException e) {
				
			}catch (InvalidSessionException e){
				
			}
		}
		if (operator == null){
			operator = new Operator();
			try{
				SecurityUtils.getSubject().logout();
			}catch (UnavailableSecurityManagerException e) {
				
			}catch (InvalidSessionException e){
				
			}
		}
		return operator;
	}
	
	public static Operator getOperator(boolean isRefresh){
		if (isRefresh){
			removeCache(CACHE_OPERATOR);
		}
		return getOperator();
	}

	public static List<Role> getRoles(){
		@SuppressWarnings("unchecked")
		List<Role> list = (List<Role>)getCache(CACHE_ROLE_LIST);
		if (list == null){
			list = roleService.list();
			putCache(CACHE_ROLE_LIST, list);
		}
		return list;
	}
	
	public static List<Menu> getMenuList(){
		@SuppressWarnings("unchecked")
		List<Menu> menuList = (List<Menu>)getCache(CACHE_MENU_LIST);
		if (menuList == null){
			Operator operator = getOperator();
			if (operator.isSuper()){
				menuList = menuService.list();
			}else{
				menuList = menuService.getMenusByOperator(operator.getId());
			}
			putCache(CACHE_MENU_LIST, menuList);
		}
		return menuList;
	}

    /**
     * 排序组合后的菜单集合
     * @return
     */
    public static List<Menu> getMenus(){
        List<Menu> menus = Lists.newArrayList();
        Menu.group(menus,getMenuList(),Menu.ROOT_ID,Menu.MERACHANT_ROOT_ID);
        return menus;
    }


	public static Operator getOperator(String id){
		if(StringUtils.isNotBlank(id)) {
			return operatorService.get(id);
		} else {
			return null;
		}
	}
	
	// ============== Operator Cache ==============
	
	public static Object getCache(String key) {
		return getCache(key, null);
	}
	
	public static Object getCache(String key, Object defaultValue) {
		Object obj = getCacheMap().get(key);
		return obj==null?defaultValue:obj;
	}

	public static void putCache(String key, Object value) {
		getCacheMap().put(key, value);
	}

	public static void removeCache(String key) {
		getCacheMap().remove(key);
	}
	
	public static Map<String, Object> getCacheMap(){
		Map<String, Object> map = Maps.newHashMap();
		try{
			Subject subject = SecurityUtils.getSubject();
			AuthorizingRealm.Principal principal = (AuthorizingRealm.Principal)subject.getPrincipal();
			return principal!=null?principal.getCacheMap():map;
		}catch (UnavailableSecurityManagerException e) {
			
		}catch (InvalidSessionException e){
			
		}
		return map;
	}


	
}
